import {reactive, ref} from "vue";

export class SerialPortService {
    constructor() {
        // 管理串口连接相关对象
        this.port = null;         // 串口实例
        this.reader = null;       // 数据读取器
        this.writer = null;       // 数据写入器
        // 状态控制
        this.reading = false;     // 读取状态标志
        // 事件回调
        this.onDataReceived = null;  // 数据接收回调
        this.onDisconnect = null;    // 断开连接回调
        this.boundHandleDisconnect = this.handleDisconnect.bind(this); // 绑定方法
    }
    async connect(config) {
        if ("serial" in navigator) {
            try {
                await this.disconnect();// 先清理旧连接
                this.port = await navigator.serial.requestPort()
                console.log('已选择设备:', this.port.getInfo(),config);
                await this.port.open({
                    baudRate: Number(config.baudRate),
                    dataBits: Number(config.dataBits),
                    stopBits: Number(config.stopBits),
                    parity: config.parity
                });
                // this.port.addEventListener('disconnect', () => {// 添加断开监听
                //     this.handleDisconnect();
                // });
                this.port.addEventListener('disconnect', this.boundHandleDisconnect); // 使用绑定后的方法
                await this.startReading();
                return true;
            } catch (error) {
                this.handleError(error);
                return false;
            }
        }else {
            alert('当前浏览器不支持串口操作,请更换Edge或Chrome浏览器');        //消息弹窗
            const msg = '浏览器不支持Web Serial API，请使用Chrome 89+或Edge 89+';
            console.error(msg);
            this.handleError(new Error(msg));
            return false;
        }
    }

    async disconnect() {
        if (!this.port) return; // 添加端口存在性检查
        this.reading = false;   //立即终止读取循环
        this.port.removeEventListener('disconnect', this.boundHandleDisconnect);// 先移除事件监听器
        await this.cleanup();
        this.port = null; // 显式置空端口实例
    }

    async cleanup() {
        if (this.writer) {      // 2. 再关闭写入器
            try {
                await this.writer.close();// await this.writer.releaseLock();
            } catch (error) {
                console.log('Writer cleanup error:', error);
            }
            this.writer = null;
        }
        if (this.reader) {      // 1. 先关闭读取器
            try {
                // console.log('Cleaning reader:', this.reader?.locked);
                await this.reader.cancel();// await this.reader.releaseLock();
                // console.log('Reader cleaned:', this.reader);
            } catch (error) {
                console.log('Reader cleanup error:', error);
            }
            this.reader = null;
        }
        if (this.port) {        // 3. 最后关闭端口
            try {
                await new Promise(resolve => setTimeout(resolve, 100));// 确保读写器已完全关闭
                await this.port.close()
            } catch (error) {
                console.error('Port close error:', error)
            }
            this.port = null
        }
    }
    async startReading() {
        try {
            const decoder = new TextDecoderStream();        // 创建解码流（二进制转文本）
            const inputStream = this.port.readable.pipeThrough(decoder);    // 建立可读流管道
            this.reader = inputStream.getReader();      // 获取读取器并启动异步读取循环
            this.reading = true;
            this.readLoop();// 立即返回，启动独立循环
            return true;
        } catch (error) {
            this.handleError(error);
            return false;
        }
    }
    async write(data) {
        if (!this.port?.writable) {
            this.handleError(new Error('串口未连接或不可写'))
            return
        }
        try {       // 延迟初始化写入器
            if (!this.writer) {
                const encoder = new TextEncoderStream()
                encoder.readable.pipeTo(this.port.writable).catch(error => {this.handleError(new Error(`管道连接失败: ${error.message}`))})// 正确连接流方向
                this.writer = encoder.writable.getWriter()
            }
            const payload = typeof data === 'string' ? data : String(data) // 处理不同数据类型
            await this.writer.write(payload)
        } catch (error) {
            this.handleError(new Error(`写入失败: ${error.message}`))
            this.handleDisconnect()
        }
    }
    async readLoop() {
        try {
            while (this.reading) {
                const { value, done } = await this.reader.read();
                if (done || !this.reading) break;
                if (value) this.onDataReceived?.(value);
            }
        } catch (error) {
            this.handleError(error);
        } finally {
            // this.reader?.releaseLock();// 已由 cancel() 自动释放，移除这行
            this.reader = null;
        }
    }
    handleError(error) {
        console.error('Serial Error:', error)
        this.handleDisconnect()
    }
    handleDisconnect() {
        if (!this.reading) return;
        this.reading = false;
        // 添加安全判断
        if (this.port) {
            this.port.removeEventListener('disconnect', this.boundHandleDisconnect);
        }
        this.cleanup().catch(console.error);
        this.onDisconnect?.()
    }
    get isConnected() {
        return !!this.port && this.port.readable && this.port.writable;
    }
}







